package com.qianfeng.dbsm.admin.filter;


import com.auth0.jwt.exceptions.TokenExpiredException;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.qianfeng.dbsm.admin.common.MyUserContextHolder;
import com.qianfeng.dbsm.admin.entity.TbMember;
import com.qianfeng.dbsm.admin.service.TbMemberService;
import com.qianfeng.dbsm.admin.util.JWTUtil;
import com.qianfeng.dbsm.admin.util.ResponseUtil;
import com.qianfeng.dbsm.common.ResponseData;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;


/**
 * 功能说明
 *
 * @author 袁俊杰
 * @date 2022-11-10 19:28:36
 */
//@WebFilter("/tbMember/*")
public class JWTfilter implements Filter {

    @Autowired
    TbMemberService tbUserService;



    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {

        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;

        httpServletRequest.setCharacterEncoding("utf-8");
        httpServletResponse.setContentType("application/");

        String path = httpServletRequest.getRequestURI();
        String token = httpServletRequest.getHeader("Authorization");


        if (path.contains("login")) {
            filterChain.doFilter(servletRequest, servletResponse);
            return;
        }
        try {
            if (token != null && JWTUtil.verify(token)) {
                String username = JWTUtil.getAccount(token);
                //验证通过，将user放入ThreadLocal
                username = JWTUtil.getAccount(token);
                TbMember user = tbUserService.getOne(new QueryWrapper<TbMember>().eq("member_account", username));
                MyUserContextHolder.setUser(user);
                filterChain.doFilter(servletRequest, servletResponse);
                return;
            }else{

                ResponseUtil.writeJson(httpServletResponse, ResponseData.fail("没有登录", null));
            }
        } catch (Exception exception) {
            if (exception instanceof TokenExpiredException) {
                //超时了,1.判断是否存在于tokenmap中，有则表示没有更新过，没有则表示此token已经更新过且已删除
                //2.判断对应的长token是否超时，没有超时即更新长短token，并删除，超时删除tokenmap
                if (JWTUtil.check(token)) {
                    String username = JWTUtil.getAccount(token);
                    //根据短token获得长token
                    String ctoken = JWTUtil.getTokenMap().get(token);
                    //判断长token是否超时
                    try {
                        JWTUtil.verify(ctoken);
                        //删除
                        JWTUtil.delete(token);
                        //更新短token
                        token = JWTUtil.create(username);
                        //更新长token
                        ctoken = JWTUtil.create2(username);
                        //放入tokenmap
                        JWTUtil.put(token, ctoken);
                        //将新的token放入到头部中
                        httpServletResponse.setHeader("token", token);
                        //将user放入ThreadLocal
                        TbMember user = tbUserService.getOne(new QueryWrapper<TbMember>().eq("username", username));
                        MyUserContextHolder.setUser(user);
                        //放行
                        filterChain.doFilter(servletRequest, servletResponse);
                        return;
                    } catch (Exception exception2) {
                        System.out.println("================进入到了长token失效=====================");
                        exception.printStackTrace();
                        ResponseUtil.writeJson(httpServletResponse, ResponseData.fail("token超时", null));
                    }

                } else {
                    exception.printStackTrace();
                    ResponseUtil.writeJson(httpServletResponse, ResponseData.fail("token失效", null));
                }
            } else {
                exception.printStackTrace();
                ResponseUtil.writeJson(httpServletResponse, ResponseData.fail("没有登录", null));

            }

        }


    }
}
